package com.iot.auth.handler;

import java.io.IOException;
import java.text.ParseException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSONObject;
import com.iot.common.core.constant.RedisConstants;
import com.iot.common.core.constant.SecurityConstants;
import com.iot.common.core.util.Md5Util;
import com.iot.common.core.util.R;
import com.iot.common.core.util.SpringContextHolder;
import com.iot.common.core.util.WebUtils;
import com.iot.common.log.event.SysLogEvent;
import com.iot.common.log.util.LogTypeEnum;
import com.iot.common.log.util.SysLogUtils;
import com.iot.common.security.domain.SimpleUser;
import com.iot.manage.api.domain.SysLog;
import com.jfinal.kit.StrKit;
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jwt.SignedJWT;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

/**
 * 登出成功后处理
 * 
 * @author love
 *
 */
@Slf4j
@Component
public class SecurityLogoutSuccessHandler implements LogoutSuccessHandler {

	private StringRedisTemplate redisTemplate;

	public SecurityLogoutSuccessHandler(StringRedisTemplate redisTemplate) {
		this.redisTemplate = redisTemplate;
	}

	@SneakyThrows
	@Override
	public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
			throws IOException, ServletException {
		String accessToken = request.getHeader(SecurityConstants.TOKEN_HEADER);
		if (!StrKit.isBlank(accessToken) && accessToken.startsWith(SecurityConstants.TOKEN_PREFIX)) {
			String token = accessToken.replace(SecurityConstants.TOKEN_PREFIX, "");
			SimpleUser simpleUser=getSimpleUser(token);
			if(simpleUser!=null) {
				String keyPrefix = RedisConstants.TOKEN_KEY_PREFIX + simpleUser.getId() + ":";
				String keySuffix = Md5Util.getMD5(token.getBytes());
				String key = keyPrefix + keySuffix;
				String authKey = key + RedisConstants.AUTH_KEY;
				redisTemplate.delete(key);
				redisTemplate.delete(authKey);
			}
		}
		SysLog sysLog = SysLogUtils.getSysLog();
		sysLog.setTitle("登出");
		Long startTime = System.currentTimeMillis();
		sysLog.setType(LogTypeEnum.NORMAL.getType());
		sysLog.setServiceId(authentication != null ? authentication.getName() : "");
		log.info("登出成功:{}", authentication != null ? authentication.getPrincipal() : "");
		WebUtils.renderJson(response, R.ok());
		sysLog.setContent("退出登录成功.");
		Long endTime = System.currentTimeMillis();
		sysLog.setTime(endTime - startTime);
		SpringContextHolder.publishEvent(new SysLogEvent(sysLog));
	}

	private SimpleUser getSimpleUser(String token) throws ParseException, JOSEException {
		SignedJWT jwt = SignedJWT.parse(token);
		Object account = jwt.getJWTClaimsSet().getClaim("payload");
		if (account != null) {
			return JSONObject.parseObject(account.toString(), SimpleUser.class);
		}
		return null;
	}

}
